package com.yunyi.lam.demo;

import com.yunyi.lam.pojo.Author;
import com.yunyi.lam.pojo.Book;
import com.yunyi.lam.utils.GetAuthors;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 终结操作示例
 *
 * @author yunyi
 */
public class FinalityLearn {
    public static void main(String[] args) {
        List<Author> authors = GetAuthors.getAuthors();
        //tesForeach(authors);
        //tesCount(authors);
        //tesMax(authors);
        //tesCollectToListOrSet(authors);
        //tesCollectToMap(authors);
        //tesAnyMatch(authors);
        //tesFindMatch(authors);
        //tesReduceCountAge(authors);
        //testReduceWithMax(authors);
        testReduceWithMaxWithOneParams(authors);
    }

    private static void testReduceWithMaxWithOneParams(List<Author> authors) {
        Optional<Integer> reduce = authors.stream().map(Author::getAge).reduce((result, element) -> {
            if (element > result) {
                result = element;
            }
            return result;
        });
        System.out.println(reduce.get());
    }

    /**
     * Reduce测试类
     * 计算年龄最大值
     *
     * @param authors 参数
     */
    private static void testReduceWithMax(List<Author> authors) {
        Integer reduce = authors.stream().map(Author::getAge).reduce(Integer.MIN_VALUE, (result, element) -> {
            if (element > result) {
                result = element;
            }
            return result;
        });
        System.out.println(reduce);
    }


    /**
     * Reduce测试类
     * 计算年龄求和
     *
     * @param authors 参数
     */
    private static void tesReduceCountAge(List<Author> authors) {
        Integer reduce = authors.stream()
                .map(author -> author.getAge())
                .reduce(0, (result, element) -> {
                    return result + element;
                });
        System.out.println(reduce);
    }

    /**
     * FindMatch测试类
     *
     * @param authors 参数
     */
    private static void tesFindMatch(List<Author> authors) {
        Optional<Author> any = authors.stream().filter(author -> author.getAge() > 13).findAny();
        any.ifPresent(author -> System.out.println(author.getName()));
    }


    /**
     * collect.toMap测试类
     *
     * @param authors 参数
     */
    private static void tesAnyMatch(List<Author> authors) {
        boolean check = authors.stream().anyMatch(author -> author.getAge() > 33);
        System.out.println(check);
    }

    /**
     * collect.toMap测试类
     *
     * @param authors 参数
     */
    private static void tesCollectToMap(List<Author> authors) {
        //获取一个Map集合，key是作者名，value是List<Book>
        Map<String, List<Book>> collect = authors.stream().distinct()
                .collect(Collectors.toMap(Author::getName, Author::getBooks));
//        Map<Object, List<Book>> collect = authors.stream().collect(Collectors.toMap(new Function<Author, Object>() {
//            @Override
//            public String apply(Author author) {
//                return author.getName();
//            }
//        }, new Function<Author, List<Book>>() {
//            @Override
//            public List<Book> apply(Author author) {
//                return author.getBooks();
//            }
//        }));
        System.out.println(collect);
    }

    /**
     * collect测试类
     *
     * @param authors 参数
     */
    private static void tesCollectToListOrSet(List<Author> authors) {
        List<String> collect = authors.stream()
                .map(author -> author.getName())
                .collect(Collectors.toList());
        System.out.println(collect);
    }

    /**
     * max测试类
     *
     * @param authors 参数
     */
    private static void tesMax(List<Author> authors) {
        Optional<Integer> max = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .map(book -> book.getScore())
                .max((o1, o2) -> o1 - o2);
        System.out.println(max.get());
    }


    /**
     * Foreach测试类
     *
     * @param authors 参数
     */
    private static void tesCount(List<Author> authors) {
        long count = authors.stream()
                .distinct()
                .count();
        System.out.println(count);
    }

    /**
     * Foreach测试类
     *
     * @param authors 参数
     */
    private static void tesForeach(List<Author> authors) {
        authors.stream().forEach(author -> System.out.println(author.getName()));
    }
}
